using imitateMacQQ.WebApi.Configures;
using imitateMacQQ.WebApi.Domain.CircleServe.Entity.dto;
using imitateMacQQ.WebApi.Domain.CircleServe.Interface;
using imitateMacQQ.WebApi.Domain.Request.utils;
using imitateMacQQ.WebApi.Repository.EFCore.Model;
using imitateMacQQ.WebApi.Repository.EFCore.Model.Circle;
using Microsoft.EntityFrameworkCore;

namespace imitateMacQQ.WebApi.Domain.CircleServe.Service;

public class UpvoteService : IUpvote
{
    public async Task<Request<bool>> UpvoteServe(Upvote dto)
    {
        bool resBoolean;
        if (dto.Like)
        {
            resBoolean = await SendLike(dto.Remarks, dto.Account);
        }
        else
        {
            resBoolean = await CancelLike(dto.Remarks, dto.Account);
        }

        return Request<bool>.Ok(resBoolean);
    }

    public async Task<bool> SendLike(string? remarks, string? account)
    {
        try
        {
            await using DataDbContext db = new DataDbContext();

            var resPeo = await db.FriendCircles.FirstOrDefaultAsync(e =>
                e.Remarks == remarks);
            if (resPeo is null || resPeo.IsDelete)
                throw new Exception("DATA IS DELETE");

            var likeInfo = await db.Likes.FirstOrDefaultAsync(e =>
                e.Remarks == remarks && e.Account == account);
            if (likeInfo is null)
                db.Likes.Add(new Like()
                {
                    Account = account,
                    Remarks = remarks
                });
            var info = await db.LikeMes.FirstOrDefaultAsync(e =>
                e.Remarks == remarks);
            if (info is not null)
            {
                info.IsRead = false;
                await db.SaveChangesAsync();
                // return true;
            }

            resPeo.LikeSum++;
            await db.LikeMes.AddAsync(new LikeMes()
            {
                Remarks = remarks,
                AcceptAccount = account,
                SendAccount = resPeo.SendAccount,
                IsRead = false
            });
            await db.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            _logHelper.LogError(ex);
            return false;
        }

        return true;
    }

    public async Task<bool> CancelLike(string? remarks, string? account)
    {
        try
        {
            await using DataDbContext db = new DataDbContext();

            var resPeo = await db.FriendCircles.FirstOrDefaultAsync(e =>
                e.Remarks == remarks);
            if (resPeo is null || resPeo.IsDelete)
                throw new Exception("DATA IS DELETE");

            var likeInfo = await db.Likes.FirstOrDefaultAsync(e =>
                e.Remarks == remarks && e.Account == account);
            if (likeInfo is null)
                throw new Exception("LIKES IS NULL! SERVE ERROR");
            db.Likes.Remove(likeInfo);

            var res = await db.LikeMes.FirstOrDefaultAsync(e =>
                e.Remarks == remarks && e.AcceptAccount == account);
            if (res is null)
                throw new Exception("LIKE-MES TABLE ERROR");
            db.LikeMes.Remove(res);

            resPeo.LikeSum--;

            await db.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            _logHelper.LogError(ex);
            return false;
        }

        return true;
    }

    public async Task<Request<string[]>> GetLikeList(string remarks)
    {
        try
        {
            await using DataDbContext db = new DataDbContext();
            var info = db.Likes.Where(e => e.Remarks == remarks).ToList();
            if (info.Count < 1)
                return Request<string[]>.Ok(null!);
            var res = new string[info.Count];
            var index = 0;
            info.ForEach(e =>
            {
                res[index] = new string(e.Account);
                ++index;
            });
            return Request<string[]>.Ok(res);
        }
        catch (Exception ex)
        {
            _logHelper.LogError(ex);
            return Request<string[]>.Ok(null!, false, ex.Message);
        }
    }

    private readonly INLogHelper _logHelper;

    public UpvoteService(INLogHelper logHelper)
    {
        _logHelper = logHelper;
    }
}